package lu.med.praxiswahl.wahlumed.client.forms;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.PrintJob;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import lu.med.praxiswahl.wahlumed.client.formdesigner.FormDesignerModelListener;
import lu.med.praxiswahl.wahlumed.client.wclient.Main;


/**
 * 
 * @author Lars Holger Roth
 */
@SuppressWarnings("serial")
public class FormsViewPanel extends JPanel implements MouseListener,
	FormDesignerModelListener
{
    public static int FORMAT_A4 = 0;
    private FormsFileFormat model;
    private double pageWidth, pageHeight;
    private Image[] background;
    public static final Font font = new Font("Arial", Font.BOLD, 14);
    public int curPage = 0;

    public FormsViewPanel(FormsFileFormat model, int pages)
    {
	// Das Panel lädt die Grafik im 1:1 Format und nimmt
	// Mausklicks an. Nach einem Mausklick wird ein neues
	// Positionsobjekt im Modell angelegt und der List
	// View über die Änderung informiert
	// Das Panel geht immer davona us, dass die Grafik mit 300 dpi
	// gescannt wurde
	// A4 wird als Standard Format angenommen
	this.setLayout(null);
	this.addMouseListener(this);
	this.model = model;
	model.addListener(this);
	background = new Image[pages];
	for (int i = 0; i < pages; i++)
	{
	    String img = model.getImagePath()[i];
	    this.loadImage(img, i);
	}
	setToFormat(FORMAT_A4);
	this.setPreferredSize(new Dimension((int) pageWidth, (int) pageHeight));
    }

    public void loadImage(String fileName, int page)
    {
	background[page] = Toolkit.getDefaultToolkit().getImage(fileName);
	MediaTracker mt = new MediaTracker(this);
	mt.addImage(background[page], 0);
	try
	{
	    mt.waitForAll();
	}
	catch (InterruptedException ex)
	{
	}
	this.repaint();
    }

    public void modelChanged()
    {
	this.repaint();
    }

    public void mouseClicked(MouseEvent e)
    {
	// Ein Klick führt zum hinzufügen eines neuen Objektes an
	// der entsprechenden Position
	String input = JOptionPane.showInputDialog("Geben Sie den Text ein :");
	if (input == null)
	    return;
	if (!input.equals(""))
	{
	    model.createObjectPosition(input, e.getX(), e.getY(), curPage);
	    this.repaint();
	}
    }

    public void mouseEntered(MouseEvent e)
    {
    }

    public void mouseExited(MouseEvent e)
    {
    }

    public void mousePressed(MouseEvent e)
    {
    }

    public void mouseReleased(MouseEvent e)
    {
    }

    @Override
    public void paint(Graphics g)
    {
	super.paint(g);
	// Zeichnet die Hintergrund Grafik ein
	if (background[curPage] != null)
	{
	    // Falls eine Grafik geladen wurde, so wird diese
	    // angezeigt
	    g.drawImage(background[curPage], 0, 0, (int) pageWidth,
		    (int) pageHeight, this);
	}
	// Zeichnet alle Einträge ein
	int x, y;
	String d;
	g.setFont(font);

	for (int i = 0; i < model.size(curPage); i++)
	{
	    x = model.getEntryX(curPage).get(i);
	    y = model.getEntryY(curPage).get(i);
	    d = model.getEntry(curPage).get(i);
	    g.drawString(d, x, y);
	}

    }

    public void print(PrintJob pj, int px, int py, boolean printBackground,
	    int fontSize, double scaleFactor)
    {
	// Nach jeder Seite muss g.dispose() aufgerufen werden
	Graphics g = pj.getGraphics();
	if (g == null)
	{
	    JOptionPane
		    .showMessageDialog(null, "Kein Drucker Context gefunden");
	    pj.end();
	    return;
	}
	g.setFont(new Font("Times New Roman", Font.PLAIN, fontSize));
	g.setColor(new Color(0, 0, 0));

	// Berechnet den Skalierungsfaktortln
	// Auf dem Bildschirm 1:1
	Dimension pageDim = pj.getPageDimension();

	double scaleX, scaleY;
	scaleX = pageWidth / pageDim.getWidth();
	scaleY = pageHeight / pageDim.getHeight();

	// Druckt alle Elemente
	double x, y;
	String d;

	if (printBackground)
	    g.drawImage(background[curPage], 0, 0, (int) pageDim.getWidth(),
		    (int) pageDim.getHeight(), this);

	for (int i = 0; i < model.size(curPage); i++)
	{
	    x = (double) model.getEntryX(curPage).get(i) / scaleX * scaleFactor;
	    y = (double) model.getEntryY(curPage).get(i) / scaleY * scaleFactor;
	    d = model.getEntry(curPage).get(i);
	    g.drawString(d, ((int) Math.round(x) + px), ((int) Math.round(y))
		    + py);
	}

	g.dispose();

	// Beenden des Print Job
	pj.end();
    }

    public void printOld()
    {
	// Stellt den Parameter String zusammen
	StringBuffer paraStr = new StringBuffer();
	paraStr.append("\"" + pageWidth + "#" + pageHeight + "#");
	for (int i = 0; i < model.size(curPage); i++)
	{
	    paraStr.append(model.getEntryX(curPage).get(i));
	    paraStr.append("#");
	    paraStr.append(model.getEntryY(curPage).get(i));
	    paraStr.append("#");
	    paraStr.append(model.getEntry(curPage).get(i));
	    paraStr.append("#");
	}
	// Entfernt das letzte zeichen
	String str = paraStr.toString();
	str = str.substring(0, str.length() - 1);
	str += "\"";
	// Ruft die externe Printer Anwendung auf
	try
	{
	    Runtime.getRuntime().exec(Main.standardPfad + "printer.exe " + str);
	}
	catch (IOException e)
	{
	    e.printStackTrace();
	}
    }

    public void setCurPage(int page)
    {
	curPage = page;
	this.modelChanged();
    }

    public void setToFormat(int format)
    {
	// Setzt die Maße des Panels auf die passende Größe,
	// damit Positionen 1:1 abgelesen werden können
	pageWidth = background[0].getWidth(this);
	pageHeight = background[0].getHeight(this);
    }
}
